package com.ymt.bpm.service.platform.fauth.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.dao.Mapper;
import com.ymt.bpm.engine.EngineConst;
import com.ymt.bpm.model.Const.Oplog;
import com.ymt.bpm.model.PGroup;
import com.ymt.bpm.model.PGroupPos;
import com.ymt.bpm.model.PGroupPosUser;
import com.ymt.bpm.service.platform.fauth.FaPgService;
import com.ymt.bpm.service.platform.log.OpLogService;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.DateUtil;
import com.ymt.bpm.util.DhxUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by Johnny on 2017/5/4.
 */
@Service
public class FaPgServiceImpl implements FaPgService {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MDao dao;

    @Autowired
    private OpLogService oplog;

    @Override
    public JSONObject query(String tenantId, String search, String sort, String order,
                            int offset, int limit, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("search", search);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<PGroup> list = dao.selectList(Mapper.PGroupMapper, "query", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (PGroup group : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(group, Const.LANG_ZH, timezoneOffset);
                node.put("_ITEM_NO", ++offset);
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONObject get(String tenantId, String groupId, String lang, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        PGroup group = dao.selectOne(Mapper.PGroupMapper, "selectByPrimaryKey", paramMap);
        JSONObject rtn = DhxUtil.toFastJsonWithDate(group, lang, timezoneOffset);
        return rtn;
    }

    @Override
    public String checkAttr(String tenantId, String attrName, String value, String groupId) {
        if (log.isDebugEnabled()) {
            log.debug("checkAttr tenantId="+tenantId);
            log.debug("checkAttr attrName="+attrName);
            log.debug("checkAttr value="+value);
            log.debug("checkAttr groupId="+groupId);
        }
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("tenantId", tenantId);
        paramMap.put("value", value);
        paramMap.put("groupId", groupId);
        int rs = dao.selectOne(Mapper.PGroupMapper, "checkAttr"+ StringUtils.capitalize(attrName), paramMap);
        if (log.isDebugEnabled()) {
            log.debug("checkAttr rs="+rs);
        }
        return rs>0 ? "false" : "true";
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject save(String tenantId, String loginName, String displayName, PGroup group) {
        if (tenantId!=null) {
            group.setTenantId(Integer.parseInt(tenantId));
        }
        int rs = 0;
        if (group.getGroupId()==null || group.getGroupId().length()==0) {
            group.setGroupId("PRG-"+ UUID.randomUUID().toString());
            group.setCreator(loginName);
            group.setCreatorName(displayName);
            group.setCreateTime(DateUtil.getGMTDate());
            rs += dao.insert(Mapper.PGroupMapper, "insertSelective", group);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.PG, group.getGroupName());
        } else {
            rs += dao.update(Mapper.PGroupMapper, "updateByPrimaryKeySelective", group);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.UPDATE, Oplog.CODE.PG, group.getGroupName());
        }
        JSONObject rtn = new JSONObject();
        rtn.put("result", rs);
        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject delete(String tenantId, String loginName, String displayName, String groupId) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        //TODO check reference in process

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);

        PGroup group = dao.selectOne(Mapper.PGroupMapper, "selectByPrimaryKey", paramMap);

        //delete references
        rs += dao.delete(Mapper.PGroupPosMapper, "deleteByGroupId", paramMap);
        rs += dao.delete(Mapper.PGroupPosUserMapper, "deleteByGroupId", paramMap);
        rs += dao.delete(Mapper.PGroupMapper, "deleteByPrimaryKey", paramMap);
        rtn.put("result", rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.DELETE, Oplog.CODE.PG, group.getGroupName());

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject delSubPos(String tenantId, String loginName, String displayName, String groupId, String posId) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        //TODO check reference in process

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        paramMap.put("posId", posId);
        rs += dao.delete(Mapper.PGroupPosMapper, "deleteByPrimaryKey", paramMap);
        rs += dao.delete(Mapper.PGroupPosUserMapper, "deleteByGroupIdPosId", paramMap);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.DELETE, Oplog.CODE.PGPOS, null);

        rtn.put("result", rs);
        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject delSubPosUser(String tenantId, String loginName, String displayName,
                                    String groupId, String posId, String userId) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        //TODO check reference in process

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        paramMap.put("posId", posId);
        paramMap.put("userId", userId);
        rs += dao.delete(Mapper.PGroupPosUserMapper, "deleteByPrimaryKey", paramMap);
        rtn.put("result", rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.DELETE, Oplog.CODE.PGPOSUSER, null);

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject clearSubPos(String tenantId, String loginName, String displayName, String groupId) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        //TODO check reference in process

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);

        //delete references
        rs += dao.delete(Mapper.PGroupPosMapper, "deleteByGroupId", paramMap);
        rs += dao.delete(Mapper.PGroupPosUserMapper, "deleteByGroupId", paramMap);
        rtn.put("result", rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CLEAR, Oplog.CODE.PGPOS, null);

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject clearSubPosUser(String tenantId, String loginName, String displayName, String groupId, String posId) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        //TODO check reference in process

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        paramMap.put("posId", posId);

        //delete references
        rs += dao.delete(Mapper.PGroupPosUserMapper, "deleteByGroupIdPosId", paramMap);
        rtn.put("result", rs);

        //记录日志
        oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CLEAR, Oplog.CODE.PGPOSUSER, null);

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject addSubPos(String tenantId, String loginName, String displayName, String groupId, String posIdsStr) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        List<PGroupPos> list = new ArrayList<PGroupPos>();
        JSONArray posIds = JSONArray.parseArray(posIdsStr);
        if (posIds!=null && posIds.size()>0) {
            for (int i=0; i<posIds.size(); i++) {
                PGroupPos pp = new PGroupPos();
                if (tenantId!=null && StringUtils.isNumeric(tenantId)) {
                    pp.setTenantId(Integer.parseInt(tenantId));
                }
                pp.setGroupId(groupId);
                pp.setPosId(posIds.getString(i));
                list.add(pp);
            }
            rs += dao.batchInsert(Mapper.PGroupPosMapper, "insert", list);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.PGPOS, null);
        }
        rtn.put(Const.AJAX_RESULT, rs);

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject addSubPosUser(String tenantId, String loginName, String displayName, String groupId, String posId, String userIdsStr) {
        JSONObject rtn = new JSONObject();
        int rs = 0;
        List<PGroupPosUser> list = new ArrayList<PGroupPosUser>();
        JSONArray userIds = JSONArray.parseArray(userIdsStr);
        if (userIds!=null && userIds.size()>0) {
            for (int i=0; i<userIds.size(); i++) {
                PGroupPosUser pp = new PGroupPosUser();
                if (tenantId!=null && StringUtils.isNumeric(tenantId)) {
                    pp.setTenantId(Integer.parseInt(tenantId));
                }
                pp.setGroupId(groupId);
                pp.setPosId(posId);
                pp.setUserId(userIds.getString(i));
                list.add(pp);
            }
            rs += dao.batchInsert(Mapper.PGroupPosUserMapper, "insert", list);

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.PGPOSUSER, null);
        }
        rtn.put(Const.AJAX_RESULT, rs);
        return rtn;
    }

    @Override
    public String queryDhx(String tenantId, String queryParams,
                           int fInd, int lInd,
                           int timezoneOffset, String lang, String ordercolumns) {
        log.debug("queryDhx queryParams="+queryParams);
        Map<String, Object> params = new HashMap<String,Object>();
        Map<String, Object> bo = new HashMap<String,Object>();
        if (queryParams!=null) {
            bo.putAll(JSONObject.parseObject(queryParams));
        }
        if (tenantId!=null) {
            bo.put(Const.TENANT_ID, tenantId);
        }
        params.put("bo", bo);
        params.put("fromRow", fInd-1);
        params.put("toRow", lInd);
        params.put("rows", lInd - fInd + 1);
        params.put("timezoneOffset", timezoneOffset);
        params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));
        log.debug("queryDhx params="+params);
        List<Map<String,?>> list = dao.selectList(Mapper.PGroupMapper, "pagingSelect", params);
        int total = dao.selectOne(Mapper.PGroupMapper, "pagingSelectCount", params);
        String[] cols = new String[]{"POS_ID", "POS_NAME", "POS_DESC", "CREATOR", "CREATE_TIME", "UPDATOR", "UPDATE_TIME"};
        String rtn= DhxUtil.toGridJsonStr(list,
                cols, fInd, total, timezoneOffset, lang);
        log.debug("queryDhx returns:\n"+rtn);
        return rtn;
    }

    @Override
    public JSONObject querySubPos(String tenantId, String groupId, String sort, String order, int offset, int limit, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<Map<String, Object>> list = dao.selectList(Mapper.PGroupPosMapper, "query", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (Map<String, Object> obj : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(obj, Const.LANG_ZH, timezoneOffset);
                node.put("_ITEM_NO", ++offset);
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONObject querySubPosUser(String tenantId, String groupId, String posId, String sort, String order, int offset, int limit, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("groupId", groupId);
        paramMap.put("posId", posId);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<Map<String, Object>> list = dao.selectList(Mapper.PGroupPosUserMapper, "query", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (Map<String, Object> obj : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(obj, Const.LANG_ZH, timezoneOffset);
                node.put("_ITEM_NO", ++offset);
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONArray allByTenantWithPos(String tenantId) {
        JSONArray rtn = new JSONArray();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        List<PGroup> groups = dao.selectList(Mapper.PGroupMapper, "query", paramMap);
        if (groups!=null && groups.size()>0) {
            for (PGroup group : groups) {
                JSONObject row = new JSONObject();
                row.put("parent", "ROOT");
                row.put("id", group.getGroupId());
                row.put("text", group.getGroupName());
                row.put("type", "PG");
                rtn.add(row);
            }
        }
        List<Map<String, Object>> poses = dao.selectList(Mapper.PGroupPosMapper, "queryAll", paramMap);
        if (poses!=null && poses.size()>0) {
            for (Map<String, Object> pos : poses) {
                JSONObject row = new JSONObject();
                row.put("parent", pos.get("GROUP_ID"));
                row.put("id", pos.get("GROUP_ID") + "_" + pos.get("POS_ID"));
                row.put("text", pos.get("POS_NAME"));
                row.put("type", "POS");
                rtn.add(row);
            }
        }
        return rtn;
    }

}
